package org.springblade.modules.admin.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.springblade.common.cache.DictCache;
import org.springblade.common.constant.MaintenanceSmsConstant;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.base.BaseEntity;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.constant.BladeConstant;
import org.springblade.core.tool.utils.Func;
import org.springblade.flow.repair.parts.vo.ProcessTaskVO;
import org.springblade.modules.admin.controller.parts.shop.PartsShopController;
import org.springblade.modules.admin.dto.ErpTransferStatusDTO;
import org.springblade.modules.admin.dto.PartsWorkSaveDTO;
import org.springblade.modules.admin.entity.*;
import org.springblade.modules.admin.enums.MaintainPlanContentEnum;
import org.springblade.modules.admin.enums.TaskStatusEnum;
import org.springblade.modules.admin.mapper.MaintainPartsWorkMapper;
import org.springblade.modules.admin.service.*;
import org.springblade.modules.admin.service.erp.IPartnerCloudPartsService;
import org.springblade.modules.admin.vo.LastPlanVO;
import org.springblade.modules.admin.vo.MalFunctionHistoryVO;
import org.springblade.modules.admin.vo.PartsMessageVO;
import org.springblade.modules.admin.vo.PartsSimpleInfoVO;
import org.springblade.modules.admin.vo.flow.ApproveVo;
import org.springblade.modules.admin.vo.parts.PartsWorkDetailVO;
import org.springblade.modules.resource.utils.SmsUtil;
import org.springblade.modules.system.entity.User;
import org.springblade.modules.system.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static org.springblade.modules.admin.service.BuildingService.PROJECT_TYPE_CODE;

@Slf4j
@Service
public class MaintainPartsWorkServiceImpl extends BaseServiceImpl<MaintainPartsWorkMapper, MaintainPartsWork> implements MaintainPartsWorkService{

	@Autowired
	private IMaintainPlanContentService planContentService;
	@Autowired
	private MaintainMalfunctionLogService malfunctionLogService;
	@Autowired
	private IMaintainMalfunctionHistoryService malfunctionHistoryService;

	@Autowired
	private IMaintainPlanContentUserService planContentUserService;
	@Autowired
	private MaintainPartsWorkSkuService partsWorkSkuService;
	@Autowired
	@Lazy
	private IPartnerCloudPartsService partnerPartsService;
	@Lazy
	@Autowired
	private IUserService userService;

	@Autowired
	private IMaintainSignService signService;


	@Override
	public MaintainPartsWork getDetailById(Long id) {
		return baseMapper.getDetailById(id);
	}

	@Override
	public Long savePartsWork(PartsWorkSaveDTO partsWork) {
		return null;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updatePartsWorkStatus(ProcessTaskVO processPass) {

		MaintainPlanContent planContent = planContentService.getOne(Wrappers.<MaintainPlanContent>lambdaQuery().eq(MaintainPlanContent::getProcessInstanceId,processPass.getProcessInstanceId()));
		if(ObjectUtil.isEmpty(planContent)){
			throw new ServiceException("未查到指定工单");
		}
		Integer planStatus = Integer.valueOf(processPass.getStatus());
		planContent.setStatus(planStatus);
		planContentService.updateById(planContent);

		ApproveVo approveVo = new ApproveVo();
		approveVo.setComment(processPass.getComment());


		// 插入部件更换记录
		malfunctionLogService.insertWorkLog(planContent.getId(), TaskStatusEnum.getTaskName(MaintainPlanContentEnum.MAINTAIN_PARTS.getId(),planStatus),planStatus, JSON.toJSONString(approveVo),processPass.getAssignee(),processPass.getAssigneeName() );
	}

	@Override
	public PartsSimpleInfoVO getPartsSimpleInfo(String processInstanceId) {
		return baseMapper.getPartsSimpleInfo(processInstanceId);
	}

	@Override
	public PartsSimpleInfoVO getPartsSimpleInfoByPlanId(Long planId) {
		return baseMapper.getPartsSimpleInfoByPlanId(planId);
	}

	@Override
    public PartsWorkDetailVO selectPartsWorkDetail(Long planId) {
		MaintainPlanContent planContent = planContentService.getById(planId);

		PartsWorkDetailVO partsWorkDetailVO = baseMapper.selectPartsWorkDetail(planId);
		if (Func.isEmpty(partsWorkDetailVO)) {
			return partsWorkDetailVO;
		}

		List<MaintainPartsWork> partsList = baseMapper.selectListByPlan(planId);
		List<MaintainPartsWorkSku> skuList = partsWorkSkuService.selectListByWorkIds(partsList.stream().map(MaintainPartsWork::getId).collect(Collectors.toList()));
		partsList.forEach(e -> {
			e.setSkuList(skuList.stream().filter(t -> t.getWorkId().equals(e.getId())).collect(Collectors.toList()));
		});
		partsWorkDetailVO.setPartsList(partsList);
		partsWorkDetailVO.setTypeName(DictCache.getValue(PROJECT_TYPE_CODE, partsWorkDetailVO.getType()));
		if(Func.isNotEmpty(partsWorkDetailVO.getMalDetailVO()) && Func.isNotEmpty(partsWorkDetailVO.getMalDetailVO().getFaultMessageList())){
			partsWorkDetailVO.getMalDetailVO().getFaultMessageList().forEach(e -> {
				if(ObjectUtil.isNotEmpty(e.getProblemItem())){
					String problemItem = String.valueOf(e.getProblemItem());
					List<String> problemNames = new ArrayList<>();
					List<String> problemItemKey = Func.toStrList(problemItem);
					for (String key : problemItemKey) {
						String problemName = DictCache.getValue("fault_problem", key);
						problemNames.add(problemName);
					}
					e.setProblemItemNames(problemNames);
				}
			});
		}
		partsWorkDetailVO.setDetailTitle(partsWorkDetailVO.getCreateUserName()+"的配件申请");

		// 查询该任务电梯最近一次完成的任务
		LastPlanVO lastPlanVO = planContentService.selectElevatorLastPlan(partsWorkDetailVO.getElevatorId(), planId);
		if (ObjectUtil.isNotEmpty(lastPlanVO)) {
			String desc = "";
			if (lastPlanVO.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_BY.getId())) {
				desc = planContentService.getPlanTemplateName(lastPlanVO.getPlanId());
			} else if (lastPlanVO.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_WX.getId())) {
				desc = "故障维修";
			} else if (lastPlanVO.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_PARTS.getId())) {
				desc = "配件更换";
			}
			lastPlanVO.setDesc(desc);
			lastPlanVO.setStatusName(TaskStatusEnum.getTaskName(lastPlanVO.getTypeStatus(), lastPlanVO.getStatus()));
		}
		partsWorkDetailVO.setLastPlanVO(lastPlanVO);

		// 查询维修操作记录
		List<MalFunctionHistoryVO> malFunctionHistories = malfunctionHistoryService.selectByPlanId(planId);
		partsWorkDetailVO.setMalFunctionHistories(malFunctionHistories);

		// 查询关联人员信息
		List<MaintainPlanContentUser> planContentUsers = planContentUserService.list(Wrappers.<MaintainPlanContentUser>lambdaQuery().eq(MaintainPlanContentUser::getPlanId, planId));
		if (ObjectUtil.isNotEmpty(planContentUsers)) {
			planContentUsers = planContentUsers.stream().filter(e -> {
				String userName = userService.getById(e.getUserId()).getRealName();
				e.setUserName(userName);
				Integer userSignCount = signService.count(Wrappers.<MaintainSign>lambdaQuery().eq(MaintainSign::getPlanId, e.getPlanId()).eq(MaintainSign::getUserId, e.getUserId()));
				e.setUserSignCount(userSignCount);
				if (planContent.getStatus().equals(TaskStatusEnum.PARTS_FINISH.getStatus())) {
					int signCount = signService.count(Wrappers.<MaintainSign>lambdaQuery().eq(MaintainSign::getPlanId, planId).eq(MaintainSign::getUserId, e.getUserId()));
					if (signCount > 0) {
						return true;
					}
				} else {
					return true;
				}
				return false;
			}).collect(Collectors.toList());
			partsWorkDetailVO.setPlanContentUsers(planContentUsers);
		}

		// 查询关联任务维修人
		List<MaintainPlanContentUser> wxPlanUsers = planContentUserService.list(Wrappers.<MaintainPlanContentUser>lambdaQuery().eq(MaintainPlanContentUser::getPlanId, partsWorkDetailVO.getMalDetailVO().getPlanId()));
		if (ObjectUtil.isNotEmpty(wxPlanUsers)) {
			List<Long> wxUserIds = wxPlanUsers.stream().map(MaintainPlanContentUser::getUserId).collect(Collectors.toList());
			String wxUserNames = userService.listByIds(wxUserIds).stream().map(User::getRealName).collect(Collectors.joining(","));
			partsWorkDetailVO.getMalDetailVO().setWxUserNames(wxUserNames);
		}
		return partsWorkDetailVO;
    }

	@Override
	public Boolean updateMalRelationParts() {
		List<MaintainPartsWork> partsWorks = baseMapper.selectOldMalRelationParts();
		if(Func.isNotEmpty(partsWorks)){
			super.updateBatchById(partsWorks);
		}
		return Boolean.TRUE;
	}

	@Override
	public MaintainPartsWork getByPlanId(Long planId) {
		return getOne(Wrappers.<MaintainPartsWork>lambdaQuery().eq(MaintainPartsWork::getPlanId, planId), false);
	}

	@Override
	public int rejectCount() {
		return baseMapper.rejectCount();
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void erpTransferStatus(ErpTransferStatusDTO params) {
		log.warn("ERP同步数据到梯无忧开始，params:[{}]", JSONObject.toJSONString(params));
		if (ObjectUtil.isEmpty(params.getPlanIds()) || ObjectUtil.isEmpty(params.getTargetStatus())) {
			log.warn("ERP同步数据到梯无忧失败，参数错误。prams:[{}]", JSONObject.toJSONString(params));
			return;
		}
		List<Long> planIds = params.getPlanIds().stream().distinct().collect(Collectors.toList());

		for (Long planId : planIds) {
			MaintainPlanContent planContent = planContentService.getById(planId);
			if (ObjectUtil.isEmpty(planContent)) {
				log.warn("ERP同步数据到梯无忧失败，未找到对应工单。planId:[{}]", planId);
				continue;
			}
			List<MaintainPartsWork> partsWorkList = this.list(Wrappers.<MaintainPartsWork>lambdaQuery().eq(MaintainPartsWork::getPlanId, planId));
//			MaintainPartsWork partsWork = getOne(Wrappers.<MaintainPartsWork>lambdaQuery().eq(MaintainPartsWork::getPlanId, planId), false);
			if (Func.isEmpty(partsWorkList)) {
				log.warn("ERP同步数据到梯无忧失败，未找到配件明细工单。planId:[{}]", planId);
				return;
			}

			switch (TaskStatusEnum.getTaskStatusEnum(MaintainPlanContentEnum.MAINTAIN_PARTS.getId(), params.getTargetStatus())) {
				case PARTS_OFFER:
				case PARTS_REPLY: {
					// 同步销售订单号，报价单号
					log.warn("erp 处理工单销售生单");
					planContent.setStatus(TaskStatusEnum.PARTS_SHIPMENTS.getStatus());
					log.warn("erp 即将修改工单");
					planContentService.updateById(planContent);
					partsWorkList.forEach(e -> e.setOtherInfo(params.getParams()));
					this.updateBatchById(partsWorkList);
					// 插入任务追踪记录
					//查询是否已有物料准备中记录
					List<MaintainMalfunctionLog> existLogList = malfunctionLogService.list(new LambdaQueryWrapper<MaintainMalfunctionLog>()
						.eq(BaseEntity::getIsDeleted, 0)
						.eq(MaintainMalfunctionLog::getPlanId, planId)
						.eq(MaintainMalfunctionLog::getExecutor, "物料准备中")
					);
					if(Func.isEmpty(existLogList)){
						malfunctionLogService.insertWorkLog(planId, TaskStatusEnum.PARTS_SHIPMENTS.getName(), TaskStatusEnum.PARTS_SHIPMENTS.getStatus(), null, AuthUtil.getUserId(), "物料准备中");
					}
					break;
				}
				case PARTS_RECEIVE: {
					log.warn("erp 处理工单待签收是否执行：{}",planContent.getStatus() == TaskStatusEnum.PARTS_PROCUREMENT.getStatus() || planContent.getStatus() == TaskStatusEnum.PARTS_SHIPMENTS.getStatus());
					// 已发货，待发货->待签收
					if (planContent.getStatus() == TaskStatusEnum.PARTS_PROCUREMENT.getStatus() || planContent.getStatus() == TaskStatusEnum.PARTS_SHIPMENTS.getStatus()) {
						planContent.setStatus(TaskStatusEnum.PARTS_RECEIVE.getStatus());
						log.warn("erp 即将修改工单");
						partsWorkList.forEach(e -> e.setOtherInfo(params.getParams()));
						this.updateBatchById(partsWorkList);
						planContentService.updateById(planContent);
						//查询是否已有维保员记录
						List<MaintainMalfunctionLog> existLogList = malfunctionLogService.list(new LambdaQueryWrapper<MaintainMalfunctionLog>()
							.eq(BaseEntity::getIsDeleted, 0)
							.eq(MaintainMalfunctionLog::getPlanId, planId)
							.eq(MaintainMalfunctionLog::getExecutor, "维保员")
						);
						// 插入任务追踪记录
						if(Func.isEmpty(existLogList)){
							malfunctionLogService.insertWorkLog(planContent.getId(), TaskStatusEnum.PARTS_RECEIVE.getName(), TaskStatusEnum.PARTS_RECEIVE.getStatus(), null, AuthUtil.getUserId(), "维保员");
						}
						break;
					}
				}
				case PARTS_ALLOCATION: {
					// 已签收，待签收->待分配
					if (planContent.getStatus() == TaskStatusEnum.PARTS_RECEIVE.getStatus()) {
						planContent.setStatus(params.getTargetStatus());
						planContentService.updateById(planContent);
						partsWorkList.forEach(e -> e.setOtherInfo(params.getParams()));
						this.updateBatchById(partsWorkList);
						//查询是否已有维保员记录
						List<MaintainMalfunctionLog> existLogList = malfunctionLogService.list(new LambdaQueryWrapper<MaintainMalfunctionLog>()
							.eq(BaseEntity::getIsDeleted, 0)
							.eq(MaintainMalfunctionLog::getPlanId, planId)
							.eq(MaintainMalfunctionLog::getExecutor, "伙伴云触发")
						);
						if(Func.isEmpty(existLogList)){
							// 插入任务追踪记录
							malfunctionLogService.insertWorkLog(planContent.getId(), TaskStatusEnum.PARTS_ALLOCATION.getName(), TaskStatusEnum.PARTS_ALLOCATION.getStatus(), null, AuthUtil.getUserId(), "伙伴云触发");
						}
						break;
					}
				}
				default:break;
			}
		}
	}

	@Override
	public Map<String, Integer> partApproveIcon() {
		return baseMapper.partApproveIcon();
	}

	@Autowired
	private PartsShopController partsShopController;
	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean script(List<Long> planIds) {
//		List<SkuInfoListVO> skuList = partsShopController.skuDetailList(null).getData();
//		if (Func.isEmpty(skuList)) {
//			return false;
//		}
//		Map<Long, SkuInfoListVO> skuMap = skuList.stream().collect(Collectors.toMap(SkuInfoListVO::getSkuId, Function.identity()));
//
//		List<MaintainPartsWork> list = list(Wrappers.<MaintainPartsWork>lambdaQuery().ge(MaintainPartsWork :: getCreateTime, DateUtil.parse("2024-12-19 00:00:00", "yyyy-MM-dd HH:mm:ss")));
//		if (ObjectUtil.isEmpty(list)) {
//			return true;
//		}
//
//		for (MaintainPartsWork partsWork : list) {
//			LambdaUpdateWrapper<MaintainPartsWork> updateWrapper = Wrappers.<MaintainPartsWork>lambdaUpdate()
//				.eq(MaintainPartsWork::getId, partsWork.getId());
//
//			boolean flag1 = false;
//			if (Func.isNotEmpty(partsWork.getSkuId())) {
//				SkuInfoListVO skuInfoListVO = skuMap.get(partsWork.getSkuId());
//				if (Func.isEmpty(skuInfoListVO)) {
//					skuInfoListVO = new SkuInfoListVO();
//				}
//				if (Func.isNotEmpty(partsWork.getSkuPartsInfo())) {
//					skuInfoListVO.setSkuItemList(partsWork.getSkuPartsInfo());
//				}
//				updateWrapper.set(MaintainPartsWork::getSkuPartsInfo, JSONObject.toJSONString(skuInfoListVO, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullStringAsEmpty));
//			}else if (Func.isNotEmpty(partsWork.getSkuPartsInfo())) {
//				SkuInfoListVO skuInfoListVO = new SkuInfoListVO();
//				skuInfoListVO.setSkuItemList(partsWork.getSkuPartsInfo());
//				updateWrapper.set(MaintainPartsWork::getSkuPartsInfo, JSONObject.toJSONString(skuInfoListVO, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullStringAsEmpty));
//			} else {
//				flag1 = true;
//			}
//
//			boolean flag2 = false;
//			if (Func.isNotEmpty(partsWork.getFinallySkuId())) {
//				SkuInfoListVO skuInfoListVO = skuMap.get(partsWork.getFinallySkuId());
//				if (Func.isEmpty(skuInfoListVO)) {
//					skuInfoListVO = new SkuInfoListVO();
//				}
//				if (Func.isNotEmpty(partsWork.getSkuPartsInfo())) {
//					skuInfoListVO.setSkuItemList(partsWork.getSkuPartsInfo());
//				}
//				updateWrapper.set(MaintainPartsWork::getFinallySkuPartsInfo, JSONObject.toJSONString(skuInfoListVO, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullStringAsEmpty));
//			}else if (Func.isNotEmpty(partsWork.getSkuPartsInfo())) {
//				SkuInfoListVO skuInfoListVO = new SkuInfoListVO();
//				skuInfoListVO.setSkuItemList(partsWork.getSkuPartsInfo());
//				updateWrapper.set(MaintainPartsWork::getFinallySkuPartsInfo, JSONObject.toJSONString(skuInfoListVO, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullStringAsEmpty));
//			} else {
//				flag2 = true;
//			}
//
//			if (flag1 && flag2) {
//				continue;
//			}
//
//			this.update(updateWrapper);
//		}

		return true;
	}

	@Override
	public List<MaintainPartsWork> selectListByPlans(List<Long> planIds) {
		return baseMapper.selectListByPlans(planIds);
	}

	@Override
	public Boolean skuSubmit(Long planId, List<MaintainPartsWorkSku> skuList) {
		if(Func.isEmpty(skuList)){
			throw new ServiceException("请求不可为空");
		}
		List<MaintainPartsWork> maintainPartsWorks = super.list(Wrappers.<MaintainPartsWork>lambdaQuery().eq(MaintainPartsWork::getPlanId, planId));
		if (Func.isEmpty(maintainPartsWorks)) {
			throw new ServiceException("配件工单明细不存在");
		}
		List<Long> partsSkuIds = skuList.stream().map(MaintainPartsWorkSku::getId).collect(Collectors.toList());
		List<Long> workId = maintainPartsWorks.stream().map(MaintainPartsWork::getId).collect(Collectors.toList());
		if(Func.isNotEmpty(partsSkuIds)){
			partsWorkSkuService.remove(Wrappers.<MaintainPartsWorkSku>lambdaQuery().in(MaintainPartsWorkSku::getWorkId,workId).notIn(MaintainPartsWorkSku::getId,partsSkuIds));
		}else {
			partsWorkSkuService.remove(Wrappers.<MaintainPartsWorkSku>lambdaQuery().in(MaintainPartsWorkSku::getWorkId,workId));
		}
		boolean isSave = partsWorkSkuService.saveOrUpdateBatch(skuList);
		partnerPartsService.syncMultiplyPurchase(planId,AuthUtil.getTenantId());
		return isSave;
	}

	@Override
	public void processPartsOrderMessage(String partsOrderId) {
		if(Func.isNotBlank(partsOrderId)){
			String[] split = partsOrderId.split("、");
			split = Arrays.stream(split).distinct().toArray(String[]::new);
			List<String> targetPhondList = new ArrayList<>();
			String buildingName = null;
			for (String planId : split) {
				// 1. 给工单创建人发短信
				PartsMessageVO partsMessageVO = baseMapper.selectPartsMessage(planId);
				if(Func.isNotEmpty(partsMessageVO.getPhone())){
					targetPhondList.add(partsMessageVO.getPhone());
				}
				if(Func.isBlank(buildingName)){
					buildingName = partsMessageVO.getBuildingName();
				}
			}
			String finalBuildingName = buildingName;
			targetPhondList.stream().distinct().collect(Collectors.toList()).forEach(phone -> {
				Map<String, String> smsParam = new HashMap<>(2);
				smsParam.put("project_name", finalBuildingName);
				SmsUtil.sendMessage(MaintenanceSmsConstant.ACCESSORIES_DELIVERY, BladeConstant.ADMIN_TENANT_ID, smsParam, phone);
			});
		}
	}
}
